<!doctype html>
<html>
<head>
    <title>Test Page</title>
    <style type="text/css" id="styleblock" class="highlight-ignore">
        h1 {
            color: #000 !important;
            font: normal 125%/1.4 Arial, sans-serif;
        }
        .yui-skin-sam .yui-console .yui-console-content {
            font-size: 10px;
            width: 32em;
        }
        .yui-skin-sam .yui-console .yui-console-bd {
            height: 50em;
        }
        .yui-skin-sam .yui-console-entry-pass .yui-console-entry-cat {
            background: #070;
            color: #fff;
        }
        .yui-skin-sam .yui-console-entry-fail .yui-console-entry-cat {
            background: #700;
            color: #fff;
        }
        .yui3-skin-sam .yui-console-entry-time {
            display: none;
        }
    </style>
</head>
<body class="yui3-skin-sam">
<h1>Tests</h1>
<div id="testbed" style="color: #000 !important"></div>

<script src="http://yui.yahooapis.com/3.0.0/build/yui/yui.js"></script>
<script>
YUI({
    filter : 'raw',
    logInclude : { TestRunner: true }
}).use('test','console', function (Y) {

var d = document,
    Assert = Y.Assert,
    suite = new Y.Test.Suite("!important related Tests"),
    sheet,
    rules;

function getCssText( allRules ) {
    var content = [], rule, i, len;

    for ( i = 0, len = allRules.length; i < len; ++i ) {
        rule = allRules[i];
        content.push(
            (rule.selectorText || rule.tagName) +
            ' { ' + rule.style.cssText + ' } ');
    }

    return content;
}

suite.add(new Y.Test.Case({
    name: "!important",

    "test !important reported in cssText for <style> block": function () {
        var style = d.getElementById('styleblock'),
            sheet = style.sheet || style.styleSheet,
            rules = sheet.cssRules || sheet.rules,
            found = false,
            i;

        for (i = rules.length - 1; i >= 0; --i) {
            if (/important/.test(rules[i].style.cssText)) {
                found = true;
                break;
            }
        }

        Assert.isTrue(found);
    },

    "test !important reported in cssText for <h1 style=>": function () {
        var x = d.getElementById('testbed').style;

        Assert.isTrue(!!/important/.test(x.cssText));

        // Opera refreshes cssTest after a style property is changed
        x.color = '#111';
        Assert.isTrue(!!/important/.test(x.cssText));
    },

    "test new sheet with important": function () {
        var s = d.createElement('style'),
            css;

        css = "#foo { color: red !important; } #bar { height: 100px; }";
        s.type = 'text/css';

        if (s.styleSheet) {
            s.styleSheet.cssText = css;
        } else {
            s.appendChild( d.createTextNode(css) );
        }

        d.getElementsByTagName('head')[0].appendChild( s );

        sheet = s.sheet || s.styleSheet,
        rules = sheet.cssRules || sheet.rules;

        Assert.areEqual( 2, rules.length, "Missing the !important rule?" );

        css = getCssText( rules );

        Y.log( css.join("\n"), "info", "TestRunner" );

        Assert.isTrue( /important/i.test( css.join('') ),
            "No parsed rule reports !important in its cssText");
    },

    "test new rule with important": function () {
        if ( sheet.insertRule ) {
            sheet.insertRule( ".foo { background-color: #000 !important; }", 2 );
        } else {
            sheet.addRule( ".foo", "background-color: #000 !important;", 2 );
        }

        var css = getCssText( rules ),
            m   = css.join('').match( /important/gi ) || [];

        Y.log( css.join("\n"), "info", "TestRunner" );

        Assert.areEqual( 3, rules.length, "Missing the inserted !important rule?" );
        Assert.areEqual( 2, m.length, "Not reporting !important in the cssText" );

    },

    "test new property with important": function () {
        var rule = rules[1] || Assert.fail("Unable to find a rule");

        rule.style.paddingBottom = '10px !important';

        Y.log( getCssText( rules ).join("\n"), "info", "TestRunner" );

        // !important shouldn't show up in value
        Assert.areEqual( '10px', rule.style.paddingBottom );

        // but should be in the cssText
        Assert.isTrue(
            /padding.*?:\s*10px\s*!\s*important/i.test( rule.style.cssText ) );
    },

    "test existing property with important": function () {
        for ( var i = rules.length - 1, rule; i >= 0; --i ) {
            rule = rules[i];

            if ( /bar/.test( rule.selectorText ) ) {
                rule.style.height = '5em !important';

                Y.log( getCssText( rules ).join("\n"), "info", "TestRunner" );

                // !important shouldn't show up in value
                Assert.areEqual( '5em', rule.style.height );

                // but should be in the cssText
                Assert.isTrue(
                    /height.*?:\s*5em\s*!\s*important/i.test(
                        rule.style.cssText ) );

                break;
            }
        }
    },

    "test set property with important via cssText": function () {
        var p = d.createElement('p');

        p.style.cssText = 'text-align: right !important';

        Y.log( getCssText( [p] ).join("\n"), "info", "TestRunner" );

        // !important should not show up in property value
        Assert.areEqual( 'right', p.style.textAlign );

        // but it should in cssText
        Assert.isTrue(
            /text-align\s*:\s*right !\s*important/i.test(p.style.cssText) );

        // Opera refreshes cssTest after a style property is changed
        p.style.color = '#111';
        Assert.isTrue(
            /text-align\s*:\s*right !\s*important/i.test(p.style.cssText) );
    },

    "test off dom style property with important": function () {
        var p = d.createElement('p');

        p.style.color = '#000';
        p.style.textAlign = 'right !important';

        Y.log( getCssText( [p] ).join("\n"), "info", "TestRunner" );

        // !important should not show up in property value
        Assert.areEqual( 'right', p.style.textAlign );

        // but it should in cssText
        Assert.isTrue(
            /text-align\s*:\s*right !\s*important/i.test(p.style.cssText),
            "value containing !important did not update cssText with !important");
    },

    "test on dom style property with important": function () {
        d.body.style.color = '#000';
        d.body.style.textAlign = 'right !important';

        Y.log( getCssText( [d.body] ).join("\n"), "info", "TestRunner" );

        // !important should not show up in property value
        Assert.areEqual( 'right', d.body.style.textAlign );

        // but it should in cssText
        Assert.isTrue(
            /text-align\s*:\s*right !\s*important/i.test(d.body.style.cssText),
            "value containing !important did not update cssText with !important");
    },

    "test setProperty + getPropertyPriority": function () {
        d.body.style.setProperty("color", "#555", "important");

        Assert.areEqual("important", d.body.style.getPropertyPriority("color"));
    },

    "test style.prop = x + getPropertyPriority": function () {
        d.body.style.paddingLeft = "3px !important";

        Assert.areEqual("important", d.body.style.getPropertyPriority("padding-left"));
    }
}));

var yconsole = new Y.Console({
    contentBox:"log",
    newestOnTop: false,
    height: '600px'
}).render();

Y.Test.Runner.add(suite);

Y.Test.Runner.run();

});
</script>
</body>
</html>
